package org.abc.fund.controller.dataSource;
import lombok.RequiredArgsConstructor;
import org.abc.fund.service.dataSourceCollection.BatchDataCollectionService;
import org.abc.fund.service.dataSourceCollection.FundDataUpdateStrategyService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;

/**
 * 批量数据采集Controller
 */
@RestController
@CrossOrigin
@RequestMapping("/api/v1/batch-collection")
@RequiredArgsConstructor
public class BatchCollectionController {

    private final BatchDataCollectionService batchCollectionService;
    private final FundDataUpdateStrategyService strategyService;

    @PostMapping("/execute")
    public ResponseEntity<?> executeBatchCollection(
            @RequestBody BatchDataCollectionService.BatchCollectionConfig config) {
        BatchDataCollectionService.BatchCollectionResult result =
                batchCollectionService.executeBatchCollection(config);
        return ResponseEntity.ok(buildResponse(result));
    }

    @PostMapping("/execute/plan/{planCode}")
    public ResponseEntity<?> executeByPlan(
            @PathVariable String planCode,
            @RequestBody PresetPlanRequest request) {
        FundDataUpdateStrategyService.DataUpdatePlan plan = FundDataUpdateStrategyService.DataUpdatePlan
                .fromCode(planCode)
                .orElseThrow(() -> new IllegalArgumentException("Unknown plan code: " + planCode));
        BatchDataCollectionService.BatchCollectionConfig config =
                strategyService.buildConfig(
                        plan,
                        request.getUsername(),
                        request.getPassword(),
                        request.getFundCodes());
        BatchDataCollectionService.BatchCollectionResult result =
                batchCollectionService.executeBatchCollection(config);
        return ResponseEntity.ok(buildResponse(result));
    }

    private Map<String, Object> buildResponse(BatchDataCollectionService.BatchCollectionResult result) {
        Map<String, Object> response = new HashMap<>();
        response.put("status", result.isSuccess() ? "success" : "fail");
        response.put("message", result.getMessage());
        int progress = 0;
        if (result.getTotalFunds() > 0) {
            progress = (int) (((double) result.getSuccessCount() /
                    (double) result.getTotalFunds()) * 100);
        }
        response.put("progress", progress);
        Map<String, List<Map<String, Object>>> preview = new HashMap<>();
        for (BatchDataCollectionService.FundCollectionResult fund : result.getFundResults()) {
            fund.getRawDataByDataType().forEach((type, records) -> {
                preview.computeIfAbsent(type, k -> new ArrayList<>());
                preview.get(type).addAll(
                        records.stream().limit(3).toList()
                );
            });
        }

        response.put("preview", preview);
        response.put("stats", result.getDataTypeStats());
        response.put("totalFunds", result.getTotalFunds());
        response.put("totalTypes", result.getTotalDataTypes());
        return response;
    }

    @lombok.Data
    public static class PresetPlanRequest {
        private String username;
        private String password;
        private List<String> fundCodes;
    }
}
